package org.xbdframework.dao.support.pagehelper;

import java.util.HashMap;
import java.util.Map;

import org.xbdframework.dao.core.PageInfo;
import org.xbdframework.jdbc.core.SqlAndParam;

import org.apache.commons.lang3.ArrayUtils;

import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;

public class OraclePageHelper extends JdbcPageHelper {

    @Override
    public SqlAndParam<Map<String, Object>> paged(String sql, Map<String, Object> parameters, PageInfo pageInfo) {
        Map<String, Object> temp = new HashMap<>();
        temp.putAll(parameters);

        if (pageInfo.getPageNum() != 1) {
            String pSql = "select *\n" + "  from (select row_.*, rownum rownum_\n"
                    + "          from (" + sql + ") row_\n"
                    + "         where rownum <= :endRow_)\n"
                    + " where rownum_ >= :startRow_";

            temp.put("startRow_", pageInfo.getStartRow());
            temp.put("endRow_", pageInfo.getEndRow());

            return new SqlAndParam<>(pSql, temp);
        }

        String pSql = "select row_.*, rownum rownum_\n" + "  from (" + sql
                + ") row_\n" + "  where rownum <= :endRow_";

        temp.put("endRow_", pageInfo.getEndRow());

        return new SqlAndParam<>(pSql, temp);
    }

    @Override
    public SqlAndParam<SqlParameterSource> paged(String sql, SqlParameterSource parameters, PageInfo pageInfo) {
        MapSqlParameterSource temp = buildParameters(parameters);

        if (pageInfo.getPageNum() != 1) {
            String pSql = "select *\n" + "  from (select row_.*, rownum rownum_\n"
                    + "          from (" + sql + ") row_\n"
                    + "         where rownum <= :endRow_)\n"
                    + " where rownum_ >= :startRow_";

            temp.addValue("startRow_", pageInfo.getStartRow());
            temp.addValue("endRow_", pageInfo.getEndRow());

            return new SqlAndParam<>(pSql, temp);
        }

        String pSql = "select row_.*, rownum rownum_\n  from (" + sql
                + ") row_\n where rownum <= :endRow_";

        temp.addValue("endRow_", pageInfo.getEndRow());

        return new SqlAndParam<>(pSql, temp);
    }

    @Override
    public SqlAndParam<Object[]> paged(String sql, Object[] parameters, PageInfo pageInfo) {
        if (pageInfo.getPageNum() != 1) {
            String pSql = "select *\n" + "  from (select row_.*, rownum rownum_from("
                    + sql + ") row_ where rownum <= ?)\n" + " where rownum_ >= ?";

            Object[] tempArray = ArrayUtils.add(parameters, pageInfo.getEndRow());
            tempArray = ArrayUtils.add(tempArray, pageInfo.getStartRow());

            return new SqlAndParam<>(pSql, tempArray);
        }

        String pSql = "select row_.*, rownum rownum_\n" + "  from (" + sql + ") row_"
                + "  where rownum <= ?";

        Object[] tempArray = ArrayUtils.add(parameters, pageInfo.getEndRow());

        return new SqlAndParam<>(pSql, tempArray);
    }
}
